package top.zhaoyuliu.logbook.server.connect.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import lombok.extern.slf4j.Slf4j;
import top.zhaoyuliu.logbook.client.builder.Alarm;
import top.zhaoyuliu.logbook.client.builder.LbBuilder;
import top.zhaoyuliu.logbook.server.connect.client.ClientStart;
import top.zhaoyuliu.logbook.server.connect.thread.AlarmThreadPool;
import top.zhaoyuliu.logbook.server.properties.LbMailProperties;

/**
 * Copyright © 2021 Arain. All rights reserved.
 *
 * @Title: TaskService.java
 * @Prject: logbook-server
 * @Package: top.zhaoyuliu.logbook.server.connect.service
 * @Description: <功能详细描述>
 * @author: Arain
 * @date: 2021年1月27日 上午11:30:07
 * @version: V1.0
 */
@Slf4j
public class TaskService {

	private MailAccount account;

	public String handlerTask(ClientStart clientStart) {
		String node = null;
		int nodeTaskNum = clientStart.getLbServiceProperties().getNodeTaskNum();
		int l = clientStart.getTaskNum().get();
		if (l < nodeTaskNum) {
			return node;
		}
		Map<String, Integer> nodeTask = clientStart.getNodeTask();
		if (ObjectUtil.isEmpty(nodeTask)) {
			return node;
		}
		List<Entry<String, Integer>> list = new ArrayList<>(nodeTask.entrySet());
		Collections.sort(list, (o1, o2) -> (o1.getValue() - o2.getValue()));

		Integer value = list.get(0).getValue();
		if (l > value) {
			node = list.get(0).getKey();
		}
		return node;
	}

	public void alarm(List<LbBuilder> list, MongoTemplate mongoTemplate, LbMailProperties properties) {
		if (properties.isEnabled() && StrUtil.isNotBlank(properties.getFrom())
				&& StrUtil.isNotBlank(properties.getHost()) && StrUtil.isNotBlank(properties.getPass())) {
			if (ObjectUtil.isNull(account)) {
				account = new MailAccount();
				account.setUser(properties.getUser());
				account.setFrom(properties.getFrom());
				account.setPass(properties.getPass());
				account.setPort(properties.getPort());
				account.setHost(properties.getHost());
			}
			AlarmThreadPool.INSTANCE.executor().execute(new Runnable() {
				@Override
				public void run() {
					try {
						List<LbBuilder> in = list;
						Map<String, List<LbBuilder>> collect = in.stream()
								.collect(Collectors.groupingBy(LbBuilder::getAppId));
						for (Entry<String, List<LbBuilder>> entry : collect.entrySet()) {
							Alarm alarm = mongoTemplate.findOne(new Query(Criteria.where("appId").is(entry.getKey())),
									Alarm.class);
							if (ObjectUtil.isNotNull(alarm)) {
								if (StrUtil.isNotBlank(alarm.getKeywords())) {
									String[] split = alarm.getKeywords().split(",");
									List<String> filter = entry.getValue().stream()
											.filter(o -> o.getLevel().equals(alarm.getLevel())
													&& checkKeyWords(o.getContent(), Arrays.asList(split)))
											.map(o -> o.getTrackId()).collect(Collectors.toList());
									if (CollectionUtil.isNotEmpty(filter)) {
										StringBuffer subject = new StringBuffer();
										subject.append("日志监控告警<").append(entry.getKey()).append(">");
										StringBuffer content = new StringBuffer();
										content.append("应用标识").append(entry.getKey()).append("发生等级")
												.append(alarm.getLevel()).append("告警").append(" 链路号 :")
												.append(String.join(",", filter)).append(" 关键字集合:")
												.append(String.join(",", split));
										MailUtil.send(account, Arrays.asList(alarm.getUsers().split(",")),
												subject.toString(), content.toString(), false);
									}
								} else {
									List<String> filter = entry.getValue().stream()
											.filter(o -> o.getLevel().equals(alarm.getLevel())).map(o -> o.getTrackId())
											.collect(Collectors.toList());
									if (CollectionUtil.isNotEmpty(filter)) {
										StringBuffer subject = new StringBuffer();
										subject.append("日志监控告警<").append(entry.getKey()).append(">");
										StringBuffer content = new StringBuffer();
										content.append("应用标识").append(entry.getKey()).append("发生等级")
												.append(alarm.getLevel()).append("告警").append(" 链路号 :")
												.append(String.join(",", filter));
										MailUtil.send(account, Arrays.asList(alarm.getUsers().split(",")),
												subject.toString(), content.toString(), false);
									}
								}
							}
						}
					} catch (Exception e) {
						e.printStackTrace();
						log.warn("告警信息发送失败");
					}
				}
			});
		}
	}

	private boolean checkKeyWords(String content, List<String> keywords) {
		boolean flag = false;
		for (String keyword : keywords) {
			if (content.contains(keyword)) {
				flag = true;
				break;
			}
		}
		return flag;
	}
}
